﻿
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Audio;
//规定音效名不能存在相同

public enum PlayType
{
    Sequential,//按顺序播放完队列音效
    Random//随机播放一次队列的音效
}

public class AudioService : ILogic
{
    GameRoot gameRoot;
    public AudioMixer mixer;
    private AudioRegister audioRegister;
    private Dictionary<string, AudioMapInfo> audioDic = new Dictionary<string, AudioMapInfo>();
    //创建三个音效播放组件
    public Dictionary<int, AudioSourceItem> isPlayingDic;
    private int id = 0;
    private GameObject SFXRoot;
    private GameObject SFXAudioSourcePrefab;
    private GameObject BGMAudioSourcePrefab;
    public void OnInit()
    {
        gameRoot = GameRoot.Instance;
        Init();
    }
    public void OnEnterState()
    {

    }

    private void Init()
    {
        mixer = gameRoot.resService.LoadPrefab<AudioMixer>(GameResPathConfig.mainMixer, false);
        audioRegister = gameRoot.resService.LoadPrefab<AudioRegister>(GameResPathConfig.audioRegister, false);
        audioRegister.Init();
        SFXAudioSourcePrefab = gameRoot.resService.LoadPrefab<GameObject>(GameResPathConfig.SFXAudioSourcePrefab, false);
        BGMAudioSourcePrefab = gameRoot.resService.LoadPrefab<GameObject>(GameResPathConfig.BGMAudioSourcePrefab, false);
        foreach (var audioItem in audioRegister.audioClipList)
        {
            audioDic[audioItem.audioName] = audioItem;
        }
        isPlayingDic = new Dictionary<int, AudioSourceItem>();
        if (SFXRoot == null)
        {
            SFXRoot = new GameObject("AudiRoot");
            SFXRoot.transform.parent = gameRoot.transform;
        }
        else
        {
            for (int i = 0; i < SFXRoot.transform.childCount; i++)
            {
                GameObject.Destroy(SFXRoot.transform.GetChild(i));
            }
        }
        if (!gameRoot.EnableGameSave)
        {
            return;
        }
        SettingData settingData = gameRoot.dataService.GetLastDataSettingData();
        SetSFXVolume(settingData.GameSFXVolume);
        SetBGMVolume(settingData.GameMusicVolume);
    }

    public void OnUpdate()
    {

    }

    public void UnInit()
    {

    }
    public int PlayAudioRandomPitch(string audioRegisterName,Vector2 PitchRange, PlayType playType = PlayType.Random,bool is3D = false, bool isLoop = false, AudioType audioType = AudioType.SFX, float time = 0, Transform parent = null)
    {
        if (audioDic.TryGetValue(audioRegisterName, out var audio))
        {
            if (audio.maxShowCount > 0 && audio.currentCount >= audio.maxShowCount)
            {
                this.Warn($"Tip:{audioRegisterName}音效已达到最大数量,无法再次生成");
                return default;
            }
            audio.currentCount++;
            return PlayAudio(audio.audioName, audio.audioClips, playType, isLoop, audioType, is3D, PitchRange, time, parent);
        }
        else
        {
            this.Warn(audioRegisterName + " is not in audioDic!");
            return default;
        }
      
    }
    public int PlayAudio(AudioClip audioClip,bool isLoop = false ,bool is3D = false,float time = 0)
    {
        AudioClip[] audioClips = new AudioClip[1] { audioClip };
        return PlayAudio(null, audioClips, PlayType.Random, isLoop, AudioType.BGM,is3D, Vector2.one);
    }
    int BGMAudioID;
        /// <summary>
        /// 播放音效注册表中的音效
        /// </summary>
        /// <param name="audioName"></param>
        /// <param name="isLoop"></param>
        /// <param name="time"></param>
        /// <returns></returns>
    public int PlayBGM(string audioName,PlayType playType,bool isLoop = false,float time = 0)
    {
        if (isPlayingDic.TryGetValue(BGMAudioID, out var audioSourceItem))
        {
            audioSourceItem.Stop();
        }
        BGMAudioID = PlayAudio_2D(audioName,  playType ,isLoop, AudioType.BGM, time);
        return BGMAudioID;
    }
    public int PlayAudio_3D(string audioRegisterName, PlayType playType = PlayType.Random, bool isLoop = false, AudioType audioType = AudioType.SFX, float time = 0, Transform parent = null)
    {
        if (audioDic.TryGetValue(audioRegisterName, out var audio))
        {
            if (audio.maxShowCount > 0 && audio.currentCount >= audio.maxShowCount)
            {
                this.Warn($"Tip:{audioRegisterName}音效已达到最大数量,无法再次生成");
                return default;
            }
            audio.currentCount++;
            return PlayAudio(audio.audioName, audio.audioClips, playType,isLoop, audioType, true,Vector2.one, time, parent);
        }
        else
        {
            this.Warn(audioRegisterName + " is not in audioDic!");
            return default;
        }
    }
    public int PlayAudio_2D(string audioName,PlayType playType = PlayType.Random, bool isLoop = false, AudioType audioType = AudioType.SFX, float time = 0)
    {
        if (audioDic.TryGetValue(audioName, out var audio))
        {
            if (audio.maxShowCount > 0 && audio.currentCount >= audio.maxShowCount)
            {
                this.Warn($"Tip:{audioName}音效已达到最大数量,无法再次生成");
                return default;
            }
            audio.currentCount++;
            return PlayAudio(audio.audioName, audio.audioClips, playType, isLoop, audioType, false, Vector2.one, time);
        }
        else
        {
            this.Warn(audioName + " is not in audioDic!");
            return default;
        }
    }
    private int PlayAudio(string RegisterName,AudioClip[] audioClips,PlayType playType, bool isLoop, AudioType audioType, bool is3D, Vector2 RandomPitch , float time = 0, Transform parent = null)
    {
        if (audioClips == null) { return default; }
        AudioSourceItem audioSourceItem = null;
        if (audioType == AudioType.SFX)
        {
            audioSourceItem = GetSFXAudioSource();
        }
        else if (audioType == AudioType.BGM)
        {
            audioSourceItem = GetBGMAudioSource();
        }
       
        if (parent != null)
        {
            audioSourceItem.transform.parent = parent;
            audioSourceItem.transform.localPosition = Vector3.zero;
            audioSourceItem.transform.localRotation = Quaternion.identity;
        }
        int id = GenerateID();
        //注册正在播放的音效播放器
        isPlayingDic[id] = audioSourceItem;
        //创建音效信息
        if (audioClips.Length == 1)
        {
            audioSourceItem.PlaySingleAudio(RegisterName, audioClips[0], RandomPitch, is3D, isLoop, id, time);
        }
        else if(audioClips.Length>1)
        {
            audioSourceItem.PlayAudios(RegisterName, audioClips, playType, RandomPitch, isLoop, id, time, is3D);
        }
        else
        {
            return -1;
        }
        return id;
    }
    public void StopSFX(int id)
    {
        if (isPlayingDic.TryGetValue(id, out var item))
        {
            item.Stop();
        }
    }
    private AudioSourceItem GetSFXAudioSource()
    {
        var item = gameRoot.resService.LoadItem(SFXAudioSourcePrefab, SFXRoot.transform, Vector3.zero, Quaternion.identity);
        return (item.item as AudioSourceItem);
    }
    private AudioSourceItem GetBGMAudioSource()
    {
        var item = gameRoot.resService.LoadItem(BGMAudioSourcePrefab, SFXRoot.transform, Vector3.zero, Quaternion.identity);
        return (item.item as AudioSourceItem);
    }

    public void Recycle(AudioSourceItem sourceItem, int audioID)
    {
        if (sourceItem == null)
        {
            return;
        }
        sourceItem.transform.parent = SFXRoot.transform;
        if (isPlayingDic.ContainsKey(id))
        {
            isPlayingDic.Remove(id);
        }
        if ((sourceItem.RegisterAudioName != null && sourceItem.RegisterAudioName != string.Empty) && audioDic.TryGetValue(sourceItem.RegisterAudioName,out var audioMapInfo))
        {
            audioMapInfo.currentCount--;
        }
        sourceItem.transform.parent = SFXRoot.transform;
        sourceItem.gameObject.SetActive(false);
    }
    private int GenerateID()
    {
        while (true)
        {
            ++id;
            if (id > int.MaxValue)
            {
                id = 0;
            }
            if (!isPlayingDic.ContainsKey(id))
            {
                return id;
            }
        }

    }


    private const string BGM_VOLUME_PARAM = "BGM";
    private const string SFX_VOLUME_PARAM = "SFX";

    /// <summary>
    /// 设置BGM音量
    /// </summary>
    /// <param name="percentage">0-1范围，0静音，1最大音量</param>
    public void SetBGMVolume(float percentage)
    {
        SetVolume(BGM_VOLUME_PARAM, percentage);
    }

    /// <summary>
    /// 设置音效音量
    /// </summary>
    /// <param name="percentage">0-1范围，0静音，1最大音量</param>
    public void SetSFXVolume(float percentage)
    {
        SetVolume(SFX_VOLUME_PARAM, percentage);
    }

    private void SetVolume(string parameterName, float percentage)
    {
        // 将百分比转换为分贝值（0-1 => -80dB到0dB）
        float volumeDB = percentage <= 0.0001f ?
            -80f :
            Mathf.Log10(percentage) * 20f;

        mixer.SetFloat(parameterName, volumeDB);
    }

    private float ConvertDBToPercentage(float dB)
    {
        // 处理静音和超限值
        if (dB <= -80f) return 0f;
        if (dB >= 0f) return 1f;

        // 应用公式：percentage = 10^(dB/20)
        return Mathf.Pow(10f, dB / 20f);
    }

    /// <summary>
    /// 获取BGM音量百分比（0~1）
    /// </summary>
    public float GetMusicVolume()
    {
        if (mixer.GetFloat(BGM_VOLUME_PARAM, out float dB))
        {
            return ConvertDBToPercentage(dB);
        }
        Debug.LogError("获取BGM音量失败");
        return 1f;
    }

    /// <summary>
    /// 获取音效音量百分比（0~1）
    /// </summary>
    public float GetSFXVolume()
    {
        if (mixer.GetFloat(SFX_VOLUME_PARAM, out float dB))
        {
            return ConvertDBToPercentage(dB);
        }
        Debug.LogError("获取SFX音量失败");
        return 1f;
    }

}


